package com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate;

import cn.hutool.core.date.DateUtil;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfwDoc.codeGenerator.cusType.SqfwImage;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.PictureRenderData;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.addWordUserSignature;
import static com.budwk.app.util.poiUtils.CommonFormOfficeUtils.generateWordDocument;

/**
 * @author ZY.Wang
 * @since 2023/12/21
 */
public abstract class BaseTemplatePdfGenerator {

    private String fileIdentity;

    private final Map<String, String> pdfSpecialDateFormatMap = Maps.newHashMap();

    /**
     * 特殊的日期格式处理
     * 如果某个字段 比如填表日期字段名称是filDate,需要的时间格式是"yyyy年MM月dd日"
     * 那么这个方法中写 pdfSpecialDateFormatMap.put("fillDate","yyyy年MM月dd日")
     * 在子方法中进行重写
     */
    protected void initSpecialPdfDateFormatMap() {
        pdfSpecialDateFormatMap.put("fillDate", "yyyy-MM-dd");
    }

    /**
     * 通用的创建pdf的方法
     *
     * @param pdfDTO pdf所需要的数据
     * @return pdf的结果vo
     */
    public XWPFTemplate createPdf(SqfwPdfCreateCommonBO pdfDTO) {

        boolean createFlag = pdfCreateConditionCheck(pdfDTO);
        if (!createFlag) return null;

        initSpecialPdfDateFormatMap();

        Map<String, Object> paramMap = Maps.newHashMap();

        // 填充基础信息
        BasePdfParamDTO basePdfParamDTO = pdfDTO.getBasePdfParamDTO();
        popularBasePdfParam(paramMap, basePdfParamDTO);

        // 利用反射填充其他字段信息
        popularSpecialPdfParam(paramMap, pdfDTO.getAbstractCustomerPdfCreateField());
        customerPopularPdfParam(paramMap, pdfDTO);

        String templateName = getTemplateName();

//        return CommonFormOfficeUtils.generateWordDocument(paramMap, templateName, pdfDTO.getBasePdfParamDTO().getFormSummaryTypeCode(), startTime);

        return generateWordDocument(paramMap, null,
                templateName);
//        return generateWordDocument(paramMap, templateName, pdfDTO.getBasePdfParamDTO().getFormSummaryTypeCode(), startTime);
    }

    /**
     * 填充pdf的基础信息
     *
     * @param paramMap 基础信息
     * @param pdfDTO   pdf相关信息
     */
    void popularBasePdfParam(Map<String, Object> paramMap, BasePdfParamDTO pdfDTO) {
        // 填充基础信息部分 单位信息
        String unitName = pdfDTO.getTitleUnitName();
        paramMap.put("unitName", unitName);
        paramMap.put("province",pdfDTO.getProvince());
        paramMap.put("city",pdfDTO.getCity());
        paramMap.put("district",pdfDTO.getDistrict());
        paramMap.put("county",pdfDTO.getCounty());
        paramMap.put("community",pdfDTO.getCommunity());

        // 填充创建人签名部分
        String createUsername = pdfDTO.getCreateUserName();
        String createUserSigUrl = pdfDTO.getCreateUserSigUrl();

        List<String> createUsernameList = Lists.newArrayList();
        List<String> createUserSigUrlList = Lists.newArrayList();

        if (StringUtils.isBlank(createUserSigUrl)) {
            createUsernameList.add(createUsername);
        } else {
            createUserSigUrlList.add(createUserSigUrl);
        }
        addWordUserSignature(paramMap, "cuNoSig", "cuSigs", "cuSig", createUsernameList, createUserSigUrlList, 1.0F);
        paramMap.put("createUserName", createUsername);

        // 填充事件
        paramMap.put("fillDateStr", DateUtil.format(pdfDTO.getFillDate(), "yyyy年MM月dd日"));
    }

    void popularSpecialPdfParam(Map<String, Object> paramMap, AbstractCustomerPdfCreateField abstractCustomerPdfCreateField) {

        Class<? extends AbstractCustomerPdfCreateField> fieldClass = abstractCustomerPdfCreateField.getClass();

        Field[] declaredFields = fieldClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);

            String fieldName = declaredField.getName();
            Object fieldData = null;
            try {
                fieldData = declaredField.get(abstractCustomerPdfCreateField);
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (fieldData == null && !SqfwImage.class.isAssignableFrom(declaredField.getType())) {
                paramMap.put(fieldName, "");
                continue;
            }

            // 分不同的类型进行处理，如果是字符串的话，可以直接插入数据
            if (String.class.isAssignableFrom(declaredField.getType())) {
                String fieldDataStr = (String) fieldData;
                paramMap.put(fieldName, fieldDataStr);
            }

            // 如果是时间类型，则使用默认的时间格式进行转化
            if (Date.class.isAssignableFrom(declaredField.getType())) {
                Date fileDate = (Date) fieldData;
                String dateStr = dateFormatHandler(pdfSpecialDateFormatMap, fieldName, fileDate);
                paramMap.put(fieldName, dateStr);
            }

            // 如果是照片类型则转化为图片
            if (SqfwImage.class.isAssignableFrom(declaredField.getType())) {
                if (fieldData != null) {
                    SqfwImage imageData = (SqfwImage) fieldData;

                    List<String> pictureUrlList = imageData.getImageUrlList();
                    List<Map<String, PictureRenderData>> pictures = CommonFormOfficeUtils.addWordPicture(pictureUrlList, fieldName, 11F);
                    paramMap.put(fieldName + "s", pictures);
                } else {
                    paramMap.put(fieldName + "s", Lists.newArrayList());
                }
            }

            if(!paramMap.containsKey(fieldName)){
                paramMap.put(fieldName, fieldData);
            }
        }
    }

    /**
     * 特殊时间字段格式处理器
     *
     * @param specialDateFormatMap 特殊时间格式map
     * @param fieldName            字段名称
     * @param date                 时间
     * @return 结果
     */
    private String dateFormatHandler(Map<String, String> specialDateFormatMap, String fieldName, Date date) {
        String defaultDateFormat = "yyyy-MM-dd";

        String dateFormat = defaultDateFormat;
        if (specialDateFormatMap.containsKey(fieldName)) {
            dateFormat = specialDateFormatMap.get(fieldName);
        }

        try {
            return DateUtil.format(date, dateFormat);
        } catch (Exception e) {
            return DateUtil.format(date, defaultDateFormat);
        }
    }

    /**
     * 获取模板的名称
     *
     * @return 结果
     */
    public abstract String getTemplateName();

    public abstract boolean pdfCreateConditionCheck(SqfwPdfCreateCommonBO pdfDTO);

    /**
     * 用户可以自定义一些复杂的字段
     *
     * @param paramMap 已经赋值过的参数
     * @param pdfParamBO   创建pdf提供的参数
     */
    public abstract void customerPopularPdfParam(Map<String, Object> paramMap, SqfwPdfCreateCommonBO pdfParamBO);

    public ByteArrayOutputStream generatePDFAfter(XWPFTemplate xwpfTemplate, Sqfw_formSummary_new formSummary) {
        return null;
    }

    /**
     * 获取处理的模板文件标识
     *
     * @return 文件模板标识
     */
    public String getFileIdentity() {
        return this.fileIdentity;
    }

    public void setFileIdentity(String fileIdentity) {
        this.fileIdentity = fileIdentity;
    }

}
